<?php
/**
 * WObservable.php
 * 
 * This file contains the abstract class WpObservable which provides event handling functionalities
 * @author Robert Schmidt <robert@wildpack.de>
 * @version 1.0
 * @package wildpack
 * @subpackage base
 */


/**
 * A class for event handling
 * 
 * The WpObservable class provides event handling functionalities
 * @author Robert Schmidt <robert@wildpack.de>
 * @version 1.0
 * @package wildpack
 * @subpackage base
 */
class WpObservable
{
	protected $Events = array();
	protected $Listeners = array();
	
	//####################################################################
	/**
	 * Adds an observable event to the object 
	 * @param array $eventNames An array of event names to add
	 */
	protected function addEvents($eventNames = array())
	{
		if (is_array($eventNames) !== true) {
			return;
		}
		
		$this->Events = array_merge($this->Events, $eventNames);		
	}
	
	
	//####################################################################
	/**
	 * Fires a specified event - starts all listeners of this event
	 * @return True if none of the event handlers returned false, otherwise false
	 * @param string $eventName The name of the event to fire
	 * @param object $params The parameters to forward to the handlers
	 */
	protected function fireEvent($eventName, $params)
	{
		$blnCheck = true;
		
		if (in_array($eventName, $this->Events, true) !== true) {
			return true;
		}
		if (array_key_exists($eventName, $this->Listeners) !== true) {
			return true;
		}
		
		$arrEListeners = $this->Listeners[$eventName];
		if (is_array($arrEListeners) !== true) {
			return true;
		}
		
		for ($i=0; $i<count($arrEListeners); $i++) {
			$objEListener = $arrEListeners[$i];
			if (!is_null($objEListener)) {
				$objEvent = $objEListener->obj;
				$strEFunc = $objEListener->func;
        $blnCheck = $blnCheck && call_user_func_array(array($objEvent, $strEFunc), $params);
			} else {
				$blnCheck = $blnCheck && call_user_func_array($strEFunc, $params);
			}
		}
		
		return $blnCheck;		
	}
	
	//####################################################################
	/**
	 * Adds an event handler for the specified event
	 * @return True if successfully added, otherwise false (in case the event does not exist)
	 * @param string $eventName The name of the event to add the handler
	 * @param object $object The object, the callback function is implemented in
	 * @param string $function The callback function name
	 */
	public function addListener($eventName, $object, $function)
	{
		
		if (in_array($eventName, $this->Events, true) !== true) {
			return false;
		}
		
		$objListener = new stdClass();
		$objListener->obj = $object;
		$objListener->func = $function;
		
		//-- Create key for this event in listeners array --
		if (array_key_exists($eventName, $this->Listeners) !== true) {
			$this->Listeners[$eventName] = array();
		}
		
		$this->Listeners[$eventName][] = $objListener;
		
		return true;		
	}
	
	//####################################################################
	/**
	 * A shortcut for the addListener method
	 * @return True if successfully added, otherwise false (in case the event does not exist)
	 * @param string $eventName The name of the event to add the handler
	 * @param object $object The object, the callback function is implemented in
	 * @param string $function The callback function name
	 * @see addListener()
	 */
	public function on($eventName, $object, $function)
	{
		return $this->addListener($eventName, $object, $function);
	}
	
	//####################################################################
	/**
	 * Removes the specified listener
	 * @return True if the specified listener was found and removed
	 * @param string $eventName The name of the event to remove its listener
	 * @param object $object The handlers object
	 * @param string $function The handler function name
	 */
	public function removeListener($eventName, $object, $function)
	{
		$blnReturn = false;
		
		if (in_array($eventName, $this->Events, true) !== true) {
			return false;
		}
		if (array_key_exists($eventName, $this->Listeners) !== true) {
			return false;
		}
		
		$arrEListeners = $this->Listeners[$eventName];
		if (is_array($arrEListeners) !== true) {
			return false;
		}
		
		for ($i=0; $i<count($arrEListeners); $i++) {
			$objEListeners = $arrEListeners[$i];
			if (is_null($objListener) === false) {
				if ($objListener->obj === $object && $objListener->func === $function) {
					unset($arrEListeners[$i]);
					$blnReturn = true;
				}
			}
			
		}		
		
		return $blnReturn;
	}
	
	//####################################################################
	/**
	 * A shortcut for removeListener method
	 * @return True if the specified listener was found and removed
	 * @param string $eventName The name of the event to remove its listener
	 * @param object $object The handlers object
	 * @param string $function The handler function name
	 * @see removeListener()
	 */
	public function un($eventName, $object, $function)
	{
		return $this->removeListener($eventName, $object, $function);
	}

}
/* End of file WpObservable.php */
/* Location: ./wildpack/base/WpObservable.php */ 